// 1、构造函数继承
// function Parent() {
//   this.name = "Parent name";
// }
// function Child() {
//   this.hobby = "Child";
//   Parent.call(this);
// }
// Parent.prototype.say = () => {
//   console.log("parent say");
// };

// console.log(new Child());
// Child { hobby: 'Child', name: 'Parent name' }
// 缺点： Child只能继承Parent构造函数里面的属性。不能继承Parent原型链上的。
// // // 2、原型链继承
// function Parent() {
//   this.name = "parent";
//   this.hobby = ["1", "2", 3];
// }
// function Child() {
//   this.type = "child";
// }
// Child.prototype = new Parent();
// let child = new Child();
// let child1 = new Child();
// child.name = "coderqian";
// child.hobby.push(3, 3);
// console.log(child1.hobby); //hobby = ["1", "2", 3, 3, 3];
// console.log(child1.name); // name="parent" 只对引用值有影响

// // 缺点：因为两个实例的隐式原型均指向 同一个构造函数的显示原型 构造函数的显示原型又指向 Parent 的实例 即指向同一块内存空间
// // 因此 改变一个实例的中对于父级的引用值 会改变所有实例的值
// 组合方式 解决上述两种继承的缺点
function Parent() {
  this.name = "Parent";
  this.hobby = [1, 2, 3, 4];
}
function Child() {
  Parent.call(this); // 调用一次构造函数
  this.type = "child;";
}
Child.prototype = new Parent(); // 调用两次构造函数
Parent.prototype.say = () => {
  console.log("say");
};
let child1 = new Child();
let child2 = new Child();
child2.hobby.push(1); // 不会影响公共内容

console.log(child1.hobby); // [ 1, 2, 3, 4 ]
console.log(child2.hobby); // [ 1, 2, 3, 4, 1 ]
child1.say(); // 可以引用父级原型链上的方法

// 寄生式组合继承
function Parent() {
  this.name = "Parent";
  this.hobby = [1, 2, 3, 4];
}
function Child() {
  Parent.call(this); // 调用一次构造函数
  this.type = "child;";
}
// Child.prototype=new Parent();
Child.prototype = Parent.prototype; // 将指向父类实例 改为指向父类原型
Parent.prototype.say = () => {
  console.log("say");
};
let child1 = new Child();
let child2 = new Child();
child2.hobby.push(1); // 不会影响公共内容

console.log(child1.hobby); // [ 1, 2, 3, 4 ]
console.log(child2.hobby); // [ 1, 2, 3, 4, 1 ]
child1.say(); // 可以引用父级原型链上的方法
